package com.cskaoyan.wordmemorize.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cskaoyan.wordmemorize.common.constant.CommonConstant;
import com.cskaoyan.wordmemorize.common.constant.ResultCodeEnum;
import com.cskaoyan.wordmemorize.common.exception.BusinessException;
import com.cskaoyan.wordmemorize.converter.AIReadConverter;
import com.cskaoyan.wordmemorize.converter.UserPrivilegeConverter;
import com.cskaoyan.wordmemorize.dao.entity.*;
import com.cskaoyan.wordmemorize.dao.mapper.*;
import com.cskaoyan.wordmemorize.dto.admin.PageDTO;
import com.cskaoyan.wordmemorize.dto.admin.UserVocAISituationDTO;
import com.cskaoyan.wordmemorize.dto.app.*;
import com.cskaoyan.wordmemorize.request.AIReviewReadCommand;
import com.cskaoyan.wordmemorize.request.PageRequest;
import com.cskaoyan.wordmemorize.request.UserFavoriteCommand;
import com.cskaoyan.wordmemorize.request.UserVocExampleSentenceCommand;
import com.cskaoyan.wordmemorize.service.UserPrivilegeService;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.messages.Message;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.chat.prompt.PromptTemplate;
import org.springframework.ai.chat.prompt.SystemPromptTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class UserPrivilegeServiceImpl implements UserPrivilegeService {

    @Autowired
    UserFavoriteMapper userFavoriteMapper;

    @Autowired
    UserVocRevMapper userVocRevMapper;

    @Autowired
    UserNotRememberMapper userNotRememberMapper;

    @Autowired
    VocMapper vocMapper;

    @Autowired
    VocBookMapper vocBookMapper;

    @Autowired
    VocChapBookMapper vocChapBookMapper;

    @Autowired
    VocMeaningMapper vocMeaningMapper;

    @Autowired
    UserVocExampleSentenceMapper userVocExampleSentenceMapper;

    @Autowired
    UserVocAISituationMapper userVocAISituationMapper;

    @Autowired
    UserVocAISituationOptionMapper userVocAISituationOptionMapper;

    @Autowired
    UserPrivilegeHistoryMapper userPrivilegeHistoryMapper;

    @Autowired
    UserVocBoundStatisticsMapper userVocBoundStatisticsMapper;

    @Autowired
    UserVocBoundLogMapper userVocBoundLogMapper;

    @Autowired
    AIReadConverter aiReadConverter;

    @Autowired
    UserPrivilegeConverter userPrivilegeConverter;

    @Value("classpath:/prompt/ai-read-system-message.st")
    private Resource systemResource;

    @Value("classpath:/prompt/ai-read-user-message.st")
    private Resource userResource;


    private final ChatClient chatClient;

    @Autowired
    public UserPrivilegeServiceImpl(ChatClient.Builder chatClientBuilder){
        this.chatClient = chatClientBuilder.build();
    }

    @Override
    public UserVocBookStatisticsDTO getSelectedBookStatistics(Long userId, Long bookId) {
        // 涉及到的表 user_voc_rev, voc_chap_book,voc_book
        //书籍的总单词数量，已选未学的单词数量，熟悉的单词数量，不熟悉的单词数量，一般的单词数量
        LambdaQueryWrapper<VocBookDO> vocBookWrapper = new LambdaQueryWrapper<>();
        vocBookWrapper.eq(VocBookDO::getId, bookId);
        VocBookDO vocBookDO = vocBookMapper.selectOne(vocBookWrapper);
        Integer vocCount = vocBookDO.getVocCount();  // 书籍的总单词数量

        // 根据bookId 在voc_chap_book中 得到这本书单词id的集合
        LambdaQueryWrapper<VocChapBookDO> vocChapWrapper = new LambdaQueryWrapper<>();
        vocChapWrapper.eq(VocChapBookDO::getBookId, bookId);
        List<VocChapBookDO> vocChapBookDOS = vocChapBookMapper.selectList(vocChapWrapper);
        List<Long> vocIds = vocChapBookDOS.stream().map(vocChapBookDO -> vocChapBookDO.getVocId())
                .collect(Collectors.toList());

        //根据voc id 和userId 在user_voc_rev中查找
        if(vocIds.isEmpty()){
            UserVocBookStatisticsDTO statisticsDTO = new UserVocBookStatisticsDTO();
            statisticsDTO.setTotal(vocCount);
            statisticsDTO.setUnFamiliar(0);
            statisticsDTO.setGeneral(0);
            statisticsDTO.setFamiliar(0);
            statisticsDTO.setNotStarted(0);
            statisticsDTO.setUnSelected(vocCount);
            return statisticsDTO;
        }

        //在user_voc_rev中 查找这个单词书中已经选择的单词
        LambdaQueryWrapper<UserVocRevDO> userVocRevWrapper = new LambdaQueryWrapper<>();
        userVocRevWrapper.eq(UserVocRevDO::getUserId, userId);
        userVocRevWrapper.in(UserVocRevDO::getVocId, vocIds);
        List<UserVocRevDO> userVocRevDOS = userVocRevMapper.selectList(userVocRevWrapper);

        int unSelected = vocCount - userVocRevDOS.size();
        UserVocBookStatisticsDTO statisticsDTO = new UserVocBookStatisticsDTO();

        statisticsDTO.setUnFamiliar(userVocRevMapper.selectList(userVocRevWrapper
                .eq(UserVocRevDO::getType, 1)
        ).size());
        userVocRevWrapper.clear();
        userVocRevWrapper.eq(UserVocRevDO::getUserId, userId);
        userVocRevWrapper.in(UserVocRevDO::getVocId, vocIds);
        statisticsDTO.setGeneral(userVocRevMapper.selectList(userVocRevWrapper.lt(UserVocRevDO::getReviewInterval, 365)
                .gt(UserVocRevDO::getReviewInterval,1)).size());
        userVocRevWrapper.clear();
        userVocRevWrapper.eq(UserVocRevDO::getUserId, userId);
        userVocRevWrapper.in(UserVocRevDO::getVocId, vocIds);
        statisticsDTO.setFamiliar(userVocRevMapper.selectList(userVocRevWrapper.ge(UserVocRevDO::getReviewInterval, 365)).size());
        userVocRevWrapper.clear();
        userVocRevWrapper.eq(UserVocRevDO::getUserId, userId);
        userVocRevWrapper.in(UserVocRevDO::getVocId, vocIds);
        statisticsDTO.setNotStarted(userVocRevMapper.selectList(userVocRevWrapper.eq(UserVocRevDO::getType, 0)).size());
        statisticsDTO.setTotal(vocCount);
        statisticsDTO.setUnSelected(unSelected); // 未选的单词数量

        return statisticsDTO;
    }

    @Override
    public void addFavoriteBulk(List<UserFavoriteCommand> userFavoriteCommand, Long userId) {

        for (int i = 0; i < userFavoriteCommand.size(); i++) {
            this.addFavorite(userFavoriteCommand.get(i),userId);
        }
//        userFavoriteCommand.forEach(command -> {
//            // 构建查询条件，根据用户ID和单词ID查找
//            LambdaUpdateWrapper<UserFavoriteDO> updateWrapper = new LambdaUpdateWrapper<>();
//            updateWrapper.eq(UserFavoriteDO::getUserId, userId)
//                    .eq(UserFavoriteDO::getVocId, command.getVocId());
//            // 检查是否存在记录
//            UserFavoriteDO existingFavorite = userFavoriteMapper.selectOne(updateWrapper);
//            if (existingFavorite == null) {
//                // 如果不存在记录，则插入新记录
//                UserFavoriteDO newFavorite = userPrivilegeConverter.userFavoriteCommand2DO(command);
//                userFavoriteMapper.insert(newFavorite);
//            } else {
//                // 如果存在记录，则更新记录
//                existingFavorite.setSelected(command.getSelected());
//                userFavoriteMapper.updateById(existingFavorite);
//            }
//        });
    }

    @Override
    public void addFavorite(UserFavoriteCommand userFavoriteCommand, Long userId) {
        LambdaQueryWrapper<UserFavoriteDO> wrapper = new LambdaQueryWrapper<UserFavoriteDO>()
                .eq(UserFavoriteDO::getUserId, userId)
                .eq(UserFavoriteDO::getVocId, userFavoriteCommand.getVocId());
        UserFavoriteDO userFavoriteDO = userFavoriteMapper.selectOne(wrapper);
        // 在单词表中根据单词id查找单词
        VocDO vocDetail = vocMapper.getVocDetail(Long.valueOf(userFavoriteCommand.getVocId()), userId);
        if (userFavoriteDO == null) {
            // 当数据库中没有单词的时候，插入单词
            UserFavoriteDO userFavorite = userPrivilegeConverter.userFavoriteCommand2DO(userFavoriteCommand);
            userFavorite.setVocContent(vocDetail.getContent()); //因为传进来的参数中缺少
            userFavorite.setUserId(userId);
            userFavorite.setSelected(1);
            userFavoriteMapper.insert(userFavorite);
        } else {
            userFavoriteDO.setSelected(1);
            userFavoriteMapper.updateById(userFavoriteDO);
        }
    }

    @Override
    public void cancelFavorite(List<Long> ids, Long userId) {
        // 删除用户收藏的单词
        // 构建查询条件，根据用户ID和单词ID列表删除
        LambdaUpdateWrapper<UserFavoriteDO> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(UserFavoriteDO::getUserId, userId)
                .in(UserFavoriteDO::getVocId, ids);
        userFavoriteMapper.delete(updateWrapper);
    }

    @Override
    public PageDTO<UserFavoriteDTO> getUserFavoriteList(PageRequest pageRequest, Long userId) {
        // user_favorite 表

        if (pageRequest.getPageNum() == null) {
            List<UserFavoriteDO> userFavoriteDOS = userFavoriteMapper.selectList(null);
            for (UserFavoriteDO userFavoriteDO : userFavoriteDOS) {
                Long vocId = userFavoriteDO.getVocId();
                //根据单词id在 voc_meaning表中去查找释义
                LambdaQueryWrapper<VocMeaningDO> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(VocMeaningDO::getVocId,vocId);
                List<VocMeaningDO> vocMeaningDOS = vocMeaningMapper.selectList(queryWrapper);
                userFavoriteDO.setInterpretations(vocMeaningDOS);
            }
            return userPrivilegeConverter.userFavoriteDOPage2PageDTO(userFavoriteDOS, (long) userFavoriteDOS.size());
        }
        Integer pageNum = pageRequest.getPageNum();
        Integer count = pageRequest.getCount();
        Page<UserFavoriteDO> pageParam = new Page(pageNum, count);
        LambdaQueryWrapper<UserFavoriteDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(pageRequest.getKeyword() != null,UserFavoriteDO::getVocContent, pageRequest.getKeyword());
        Page<UserFavoriteDO> userFavoriteDOPage = userFavoriteMapper.selectPage(pageParam, queryWrapper);
        List<UserFavoriteDO> records = userFavoriteDOPage.getRecords();
        for (UserFavoriteDO userFavoriteDO : records) {
            Long vocId = userFavoriteDO.getVocId();
            //根据单词id在 voc_meaning表中去查找释义
            LambdaQueryWrapper<VocMeaningDO> queryWrapper2 = new LambdaQueryWrapper<>();
            queryWrapper2.eq(VocMeaningDO::getVocId,vocId);
            List<VocMeaningDO> vocMeaningDOS = vocMeaningMapper.selectList(queryWrapper2);
            userFavoriteDO.setInterpretations(vocMeaningDOS);
        }
        return userPrivilegeConverter.userFavoriteDOPage2PageDTO(records, userFavoriteDOPage.getTotal());
    }

    @Override
    public void addUserVocSentence(UserVocExampleSentenceCommand command, Long userId) {
        UserVocExampleSentenceDO userVocExampleSentenceDO = new UserVocExampleSentenceDO();
        userVocExampleSentenceDO.setUserId(userId);
        userVocExampleSentenceDO.setVocId(Long.parseLong(command.getVocId()));
        userVocExampleSentenceDO.setSentence(command.getSentence());
        userVocExampleSentenceDO.setMeaning(command.getMeaning());
        userVocExampleSentenceDO.setVocContent(command.getVocContent());

        int effectiveRow = userVocExampleSentenceMapper.insert(userVocExampleSentenceDO);
        System.out.println("受影响行数：" + effectiveRow);
    }

    @Override
    public PageDTO<DisplayUserVocSentenceDTO> getUserVocSentence(PageRequest pageRequest, Long userId) {

        LambdaQueryWrapper<UserVocExampleSentenceDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserVocExampleSentenceDO::getUserId, userId);

        queryWrapper.like(pageRequest.getKeyword() != null, UserVocExampleSentenceDO::getVocContent, pageRequest.getKeyword());
        // 根据用户id 查user_voc_sentence表中所有的单词id
        List<Long> vocIds = userVocExampleSentenceMapper.selectList(queryWrapper)
                .stream().map(UserVocExampleSentenceDO::getVocId)
                .distinct()
                .collect(Collectors.toList());

        // 根据用户id,单词id 查user_voc_sentence表某一个单词中所有的例句,
        List<DisplayUserVocSentenceDTO> displayUserVocSentenceDTOS = new ArrayList<>(vocIds.size());
        for (int i = 0; i < vocIds.size(); i++) {
            DisplayUserVocSentenceDTO vocSentenceDTO = new DisplayUserVocSentenceDTO();

            vocSentenceDTO.setUserId(userId.toString());
            vocSentenceDTO.setVocId(vocIds.get(i).toString());
            LambdaQueryWrapper<UserVocExampleSentenceDO> queryWrapper2 = new LambdaQueryWrapper<>();
            queryWrapper2.eq(UserVocExampleSentenceDO::getUserId, userId);
            queryWrapper2.eq(UserVocExampleSentenceDO::getVocId, vocIds.get(i));
            // 有可能查到同一个单词的多条例句
            List<UserVocExampleSentenceDO> sentenceDOS =
                    userVocExampleSentenceMapper.selectList(queryWrapper2);
            //
//            Map<Long, List<String>> collect = sentenceDOS.stream()
//                    .collect(Collectors.groupingBy(
//                            UserVocExampleSentenceDO::getVocId,                     // 以 vocId 分组
//                            Collectors.mapping(
//                                    UserVocExampleSentenceDO::getVocContent,            // 提取 vocContent
//                                    Collectors.toList()                                 // 收集为 List
//                            )
//                    ));
//
            if(!sentenceDOS.isEmpty()){
                vocSentenceDTO.setVocContent(sentenceDOS.get(0).getVocContent());
            }
            List<UserVocSentenceDTO> userVocSentenceDTOS = userPrivilegeConverter.userVocSentenceDOs2DTOs(sentenceDOS);

            vocSentenceDTO.setSentences(userVocSentenceDTOS);
            displayUserVocSentenceDTOS.add(vocSentenceDTO);
        }

        return userPrivilegeConverter.displayUserVocSentenceDTOList2PageDTO(displayUserVocSentenceDTOS, (long) vocIds.size());

    }

    @Override
    public void updateUserVocSentence(UserVocExampleSentenceCommand command, Long userId) {

        LambdaUpdateWrapper<UserVocExampleSentenceDO> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper
                .eq(UserVocExampleSentenceDO::getId, command.getId())
//                .eq(UserVocExampleSentenceDO::getVocId, command.getVocId())
//                .eq(UserVocExampleSentenceDO::getUserId, userId)  // 确保只能修改自己的例句
                .set(UserVocExampleSentenceDO::getVocContent, command.getVocContent())
                .set(UserVocExampleSentenceDO::getSentence, command.getSentence())
                .set(UserVocExampleSentenceDO::getMeaning, command.getMeaning());

        int affectedRows = userVocExampleSentenceMapper.update(null, updateWrapper);
//        if (affectedRows == 0) {
//            throw new RuntimeException("更新失败，可能是例句不存在或无权修改");
//        }
    }

    @Override
    public void deleteUserVocSentence(Long id) {

    }

    @Override
    public void notRemember(Long vocId, Long userId) {

        LambdaQueryWrapper<UserVocRevDO> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(UserVocRevDO::getVocId, vocId)
                .eq(UserVocRevDO::getUserId, userId);
        List<UserVocRevDO> userVocRevDOS = userVocRevMapper.selectList(lambdaQueryWrapper);

        // 该单词在复习表中
        if (!userVocRevDOS.isEmpty()) {
            int effectiveRow = userVocRevMapper.delete(lambdaQueryWrapper);
            System.out.println("复习表受影响行数: " + effectiveRow);
        }

//        int effectiveRow1 = vocMapper.deleteById(vocId);
//        System.out.println("单词表受影响行数: " + effectiveRow1);
//
//        Map<String, Object> param = new HashMap<>();
//        param.put("voc_id", vocId);
//        int effectiveRow2 = vocChapBookMapper.deleteByMap(param);
//        System.out.println("单词书籍章节表受影响行数: " + effectiveRow2);

        UserNotRememberDO userNotRememberDO = new UserNotRememberDO();
        userNotRememberDO.setVocId(vocId);
        userNotRememberDO.setUserId(userId);
        int effectiveRow3 = userNotRememberMapper.insert(userNotRememberDO);
        System.out.println("不背单词表受影响行数: " + effectiveRow3);
    }

    @Override
    public void cancelNotRemember(Long vocId, Long userId) {
//        LambdaUpdateWrapper<VocDO> vocDOLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
//        vocDOLambdaUpdateWrapper.eq(VocDO::getId, vocId);
//        vocDOLambdaUpdateWrapper.set(VocDO::getIsDeleted, 0);
//        vocMapper.update(null, vocDOLambdaUpdateWrapper);
//
//        LambdaUpdateWrapper<VocChapBookDO> vocChapBookDOLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
//        vocChapBookDOLambdaUpdateWrapper.eq(VocChapBookDO::getVocId, vocId);
//        vocChapBookDOLambdaUpdateWrapper.set(VocChapBookDO::getIsDeleted, 0);
//        vocChapBookMapper.update(null, vocChapBookDOLambdaUpdateWrapper);

        LambdaQueryWrapper<UserNotRememberDO> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(UserNotRememberDO::getVocId, vocId)
                .eq(UserNotRememberDO::getUserId, userId);
        int effectiveRow = userNotRememberMapper.delete(lambdaQueryWrapper);
        System.out.println("不背单词表受影响行数: " + effectiveRow);
    }

    @Override
    public List<UserReviewFillWordDTO> getUserReviewFillWordTopics(List<Long> vocIds) {
        return null;
    }

    @Override
    public List<UserReviewSingleChoiceDTO> getVocSingleChoiceTopic(List<Long> vocIds) {
        return null;
    }

    @Override
    public List<UserVocAISituationDTO> getAIReviewReadOptions() {

        List<UserVocAISituationDO> situations = userVocAISituationMapper.selectList(
                new LambdaQueryWrapper<UserVocAISituationDO>()
                        .eq(UserVocAISituationDO::getStatus, 1)
        );

        if (situations.isEmpty()) {
            return null;
        }

        situations.forEach(situation -> {
            LambdaQueryWrapper<UserVocAISituationOptionDO> optionWrapper = new LambdaQueryWrapper<>();
            optionWrapper.eq(UserVocAISituationOptionDO::getSituationId, situation.getId());
            List<UserVocAISituationOptionDO> options = userVocAISituationOptionMapper.selectList(optionWrapper);
            situation.setOptions(options);
        });

        return aiReadConverter.toUserVocAISituationDTOList(situations);
    }


    @Override
    public Integer getUserVocAIReadRemainFreeCount(Long userId) {
        LambdaQueryWrapper<UserPrivilegeUseStatisticsDO> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(UserPrivilegeUseStatisticsDO::getUserId, userId);
        UserPrivilegeUseStatisticsDO user = userPrivilegeHistoryMapper.selectOne(lambdaQueryWrapper);
        if (user == null) {
            user = new UserPrivilegeUseStatisticsDO();
            user.setUserId(userId);
            user.setPrivilegeCode("review:ai:read");
            user.setUseCount(0);

            userPrivilegeHistoryMapper.insert(user);
        }

        if(user.getUseCount() >= 10){
            return 0;
        }
        else{
            return 10 - user.getUseCount();
        }
    }

    @Override
    public List<AIReviewReadDTO> getAIReviewReadContent(AIReviewReadCommand command, Long userId) {

        Integer available;
        Integer exchange;

        LambdaQueryWrapper<UserPrivilegeUseStatisticsDO> useTimesQueryWrapper = new LambdaQueryWrapper<>();
        useTimesQueryWrapper.eq(UserPrivilegeUseStatisticsDO::getUserId, userId);
        UserPrivilegeUseStatisticsDO user = userPrivilegeHistoryMapper.selectOne(useTimesQueryWrapper);
        if (user == null) {
            return null;
        }

        if (user.getUseCount() >= 10) {
            LambdaQueryWrapper<UserVocBoundStatisticsDO> vocBuondQueryWrapper = new LambdaQueryWrapper<>();
            vocBuondQueryWrapper.eq(UserVocBoundStatisticsDO::getUserId, userId);
            UserVocBoundStatisticsDO vocBound = userVocBoundStatisticsMapper.selectOne(vocBuondQueryWrapper);

            if (vocBound == null) {
                return null;
            }

            available = vocBound.getAvailable();
            exchange = vocBound.getExchange();
            if (available < 10) {
                throw new BusinessException(ResultCodeEnum.USER_VOC_BOUND_NOT_ENOUGH);
            }

            available -= 10;
            exchange += 10;
            LambdaUpdateWrapper<UserVocBoundStatisticsDO> vocBuondStatisticsUpdateWrapper = new LambdaUpdateWrapper<>();
            vocBuondStatisticsUpdateWrapper.eq(UserVocBoundStatisticsDO::getUserId, userId);
            vocBuondStatisticsUpdateWrapper.set(UserVocBoundStatisticsDO::getAvailable, available);
            vocBuondStatisticsUpdateWrapper.set(UserVocBoundStatisticsDO::getExchange, exchange);

            userVocBoundStatisticsMapper.update(vocBuondStatisticsUpdateWrapper);

            UserVocBoundLogDO userVocBoundLogDO = new UserVocBoundLogDO();
            userVocBoundLogDO.setUserId(userId);
            userVocBoundLogDO.setLogDate(LocalDate.now());
            userVocBoundLogDO.setType(CommonConstant.USER_VOC_BOUND_CHANGE_TYPE_EXCHANGE);
            userVocBoundLogDO.setCount(10);
            userVocBoundLogDO.setDescription(CommonConstant.USER_VOC_BOUND_DESCRIPTION_AI_READ);

            userVocBoundLogMapper.insert(userVocBoundLogDO);
        }

        SystemPromptTemplate systemPromptTemplate = new SystemPromptTemplate(systemResource);
        Message systemMessage = systemPromptTemplate.createMessage();

        HashMap<String, Object> paramMap = new HashMap<>();
        paramMap.put("situation", command.getSituationName());
        paramMap.put("option", command.getOptionName());
        paramMap.put("words", command.getVocList().toString());
        if ("教育模式".equals(command.getSituationName())) {
            paramMap.put("type", "短文");
        } else if ("对话模式".equals(command.getSituationName())) {
            paramMap.put("type", "对话");
        } else {
            paramMap.put("type", "故事");
        }

        PromptTemplate userPrompt = new PromptTemplate(userResource, paramMap);
        Message userMessage = userPrompt.createMessage();

        Prompt prompt = new Prompt(List.of(userMessage, systemMessage));

        LambdaUpdateWrapper<UserPrivilegeUseStatisticsDO> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(UserPrivilegeUseStatisticsDO::getUserId, userId)
                .setSql("use_count = use_count + 1");
        userPrivilegeHistoryMapper.update(null,updateWrapper);

        try {
            return chatClient.prompt(prompt)
                    .call()
                    .entity(new ParameterizedTypeReference<List<AIReviewReadDTO>>() {});
        } catch (Exception e) {
            AIReviewReadDTO singleResult = chatClient.prompt(prompt)
                    .call()
                    .entity(AIReviewReadDTO.class);
            return Collections.singletonList(singleResult);
        }
    }
}
